package com.zhouke.certificate.controller;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhouke.certificate.common.Result;
//import org.hyperledger.fabric.gateway.Contract;
//import org.hyperledger.fabric.gateway.ContractException;
//import org.hyperledger.fabric.gateway.Network;
//import org.hyperledger.fabric.sdk.Peer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;

import com.zhouke.certificate.service.ICertificatesService;
import com.zhouke.certificate.entity.Certificates;

import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.List;

import cn.hutool.core.util.StrUtil;
/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 周科
 * @since 2022-04-03
 */
@RestController
@RequestMapping("/certificates")
public class CertificatesController {
    @Resource
    private ICertificatesService certificatesService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    public static final String CERTIFICATES="CERTIFICATES";
    //新增或更新
    @PostMapping
    public Result save(@RequestBody Certificates certificates) {  // 返回 Boolean
        Integer id=certificates.getId();//根据有无Id判断是新增还是修改
        if(id==null){//新增
            try {
                //先判断证书编号是否重复
                QueryWrapper<Certificates> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("certificate_num",certificates.getCertificateNum());
                if(certificatesService.getOne(queryWrapper)!=null){//证书编号已经存在
                    return Result.error("500","证书编号已存在");
                }
                Boolean b=certificatesService.saveOrUpdate(certificates);//在新增的时候会给certificates的id字段赋值 但时state createTime等默认值还是需要插入数据库后才能直到
                //获取刚刚插入的证书  主要是为了获取 createTime等字段的值 还有数据库设置的一些默认值
                //存储到区块链中
//                Certificates certificates2=certificatesService.getById(certificates.getId());
//                String txid=addCertificate(certificates2);
            }catch (Exception e){
                e.printStackTrace();
            }
        }else{//更新
            try{
                Boolean b=certificatesService.saveOrUpdate(certificates);//在新增的时候会给certificates的id字段赋值 但时state createTime等默认值还是需要插入数据库后才能直到
                //获取刚刚插入的证书  主要是为了获取 createTime等字段的值 还有数据库设置的一些默认值
                //存储到区块链中
//                Certificates certificates2=certificatesService.getById(certificates.getId());
//                String txid=updateCertificate(certificates2);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        //删除缓存
        stringRedisTemplate.delete(CERTIFICATES);
        return Result.success();
    }
    //删除
    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id) { //返回 Boolean
        //删除缓存
        stringRedisTemplate.delete(CERTIFICATES);
        return Result.success(certificatesService.removeById(id));
    }
    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids){  //返回 Boolean
        //删除缓存
        stringRedisTemplate.delete(CERTIFICATES);
        return Result.success(certificatesService.removeByIds(ids));
    }
    //查询所有
    @GetMapping
    public Result findAll() { //返回 List<Certificates>
        //先从缓存获取数据
        String jsonStr=stringRedisTemplate.opsForValue().get(CERTIFICATES);
        List<Certificates> certificates;
        if(StrUtil.isBlank(jsonStr)){ //缓存没有数据
            certificates=certificatesService.list();
            //缓存
            stringRedisTemplate.opsForValue().set(CERTIFICATES, JSONUtil.toJsonStr(certificates));
        }else{ //缓存有数据
            certificates=JSONUtil.toBean(jsonStr,
                    new TypeReference<List<Certificates>>(){},
                    true);
        }
        return Result.success(certificates);
    }
    //根据id查询
    @GetMapping("/{id}")
    public Result findOne(@PathVariable Integer id) { // 返回 Certificates
        return Result.success(certificatesService.getById(id));
    }
        //分页查询
    //      realName:"",
    //      identity:"",
    //      certificateNum:"",
    //      state:""
    @GetMapping("/page")
    public Result findPage(@RequestParam Integer pageNum,
                                 @RequestParam Integer pageSize,
                                @RequestParam(defaultValue = "") String name,
                                @RequestParam(defaultValue = "") String identity,
                                @RequestParam(defaultValue = "") String certificateNum,
                                @RequestParam(defaultValue = "") String state,
                                @RequestParam(defaultValue = "") String startTime,
                                @RequestParam(defaultValue = "") String endTime) { //返回  Page<Certificates>
        QueryWrapper<Certificates> queryWrapper=new QueryWrapper<>();
        if(!"".equals(name)){
            queryWrapper.like("name",name);
        }
        if(!"".equals(identity)){
            queryWrapper.like("identity",identity);
        }
        if(!"".equals(certificateNum)){
            queryWrapper.like("certificate_num",certificateNum);
        }
        if(!"".equals(state)){
            queryWrapper.eq("state",state);
        }
        if(!"".equals(startTime) && !"".equals(endTime)){
            queryWrapper.ge("certificate_time",startTime);
            queryWrapper.le("certificate_time",endTime);
        }
        queryWrapper.orderByDesc("id");
        return Result.success(certificatesService.page(new Page<>(pageNum, pageSize),queryWrapper));
    }
    /**
     * 证书认证
     */
    @GetMapping("/verify")//?identity=value&certificateNum=value&state=value
    public Result verify(@RequestParam(defaultValue = "") String identity,
                         @RequestParam(defaultValue = "") String certificateNum,
                         @RequestParam(defaultValue = "") String state) {
        // 先从数据库查询
        QueryWrapper<Certificates> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("identity",identity);
        queryWrapper.eq("certificate_num",certificateNum);
        queryWrapper.eq("state",state);
        Certificates certificates=certificatesService.getOne(queryWrapper);
        //数据库中证书不存在
        if(certificates==null){
            return Result.error();
        }
        // 再从区块链查询
//        Certificates certificates1=null;
//        try {
//            certificates1=findCertificates(certificates.getId().toString());
//            System.out.println("==========区块链数据"+certificates1);
//        }catch (Exception e){
//            e.printStackTrace();
//        }
//

//        if(certificates.equals(certificates1)){
//            //如果数据库数据和区块链数据一致
//            return Result.success(certificates);
//        }else{
//            return Result.error();
//        }
        return Result.success(certificates);
    }
    //证书追溯 根据id查询历史记录
    @GetMapping("/history/{id}")
    public Result findHistory(@PathVariable Integer id) { // 返回 Certificates的历史记录
        return Result.error("400","区块链已关闭");
    }

//    private final SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

//    private String addCertificate(Certificates certificates) throws ContractException, InterruptedException, TimeoutException {
//        byte[] invokeResult = contract.submitTransaction("addCertificate",certificates.getId().toString(),
//                certificates.getUserId(),
//                certificates.getName(),
//                certificates.getSex(),
//                certificates.getIdentity(),
//                certificates.getIssuedBy(),
//                certificates.getCertificateName(),
//                certificates.getCertificateNum(),
//                simpleDateFormat.format(certificates.getCertificateTime()),
//                certificates.getCertificateLevel(),
//                certificates.getAttachment(),
//                certificates.getState(),
//                simpleDateFormat.format(certificates.getCreateTime()));
//
//        String txId = new String(invokeResult, StandardCharsets.UTF_8);
//        return txId;
//    }
//
//    private String deleteCertificate(String id) throws ContractException, InterruptedException, TimeoutException {
//        byte[] invokeResult = contract.submitTransaction("deleteCertificate",id);
////        byte[] invokeResult = contract.createTransaction("deleteCertificate")
////                .setEndorsingPeers(network.getChannel().getPeers(EnumSet.of(Peer.PeerRole.ENDORSING_PEER)))
////                .submit(id);
//        String txId = new String(invokeResult, StandardCharsets.UTF_8);
//        return txId;
//    }
//
//    private String updateCertificate(Certificates certificates) throws ContractException, InterruptedException, TimeoutException {
//        byte[] invokeResult = contract.submitTransaction("updateCertificate",certificates.getId().toString(),
//                        certificates.getUserId(),
//                        certificates.getName(),
//                        certificates.getSex(),
//                        certificates.getIdentity(),
//                        certificates.getIssuedBy(),
//                        certificates.getCertificateName(),
//                        certificates.getCertificateNum(),
//                        simpleDateFormat.format(certificates.getCertificateTime()),
//                        certificates.getCertificateLevel(),
//                        certificates.getAttachment(),
//                        certificates.getState(),
//                        simpleDateFormat.format(certificates.getCreateTime()));
//
//        String txId = new String(invokeResult, StandardCharsets.UTF_8);
//        return txId;
//    }
//
//    private Certificates findCertificates(String id)throws ContractException {
//        byte[] queryAResultBefore = contract.evaluateTransaction("getCertificateById", id);
//        String CertificateStr=new String(queryAResultBefore, StandardCharsets.UTF_8);
//        Certificates certificates= JSON.parseObject(CertificateStr,Certificates.class);
//        return certificates;
//    }
//
//    private List<HistoryCertificate> getHistoryCertificate(String id)throws ContractException {
//
//        byte[] queryAResultBefore = contract.evaluateTransaction("getHistory", id);
//        String historyCertificateStr=new String(queryAResultBefore, StandardCharsets.UTF_8);
//        List<HistoryCertificate> historyCertificateList= JSON.parseArray(historyCertificateStr,HistoryCertificate.class);
//        return historyCertificateList;
//    }

}

